package com.client.koshercook.client;


import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;

public class Fridge extends Composite {

	//open fridge button
	private Image open = new Image();
	
	//fridge main window
	private final DialogBox dialogBox = new DialogBox(false, true);
	private HorizontalPanel mainHPanel = new HorizontalPanel();
	private Image fridgeDoor = new Image("refrigerator_door.gif");
	
	//left side of the fridge panel
	private VerticalPanel mainVPanel = new VerticalPanel();

	//add button & box panel
	private HorizontalPanel buttonAndBox = new HorizontalPanel();
	private PushButton addButton = new PushButton("הוסף");
	private final IngTextBox sBox = new IngTextBox();
	
	//the option for adding the fridge to the request 
	private CheckBox useFridgeCBox = new CheckBox("הוסף תוכן מקרר לחיפוש");
	
	//ings table
	private HTML tableHeader = new HTML("מצרכים");
	private final FlexTable ingsTable = new FlexTable();
	private ScrollPanel scrollerIngsTable = new ScrollPanel(ingsTable);
	
	//lower buttons panel
	private HorizontalPanel buttons = new HorizontalPanel();
	private PushButton closeButton = new PushButton("יציאה");
	private PushButton cleanButton = new PushButton("נקה מקרר");
	
	private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
	
	private List<String> userList = new ArrayList<String>();


	public Fridge() {
		
		open.setSize("132px", "24px");
		open.setUrl("fridge_off.gif");
		open.addMouseOverHandler(new MouseOverHandler(){
			public void onMouseOver(MouseOverEvent event) {
				open.setUrl("fridge_on.gif");
			}
		});
		open.addMouseOutHandler(new MouseOutHandler(){
			public void onMouseOut(MouseOutEvent event) {
				open.setUrl("fridge_off.gif");
			}
		});
		open.setTitle("צרו לכם מקרר שבו יש רכיבים שתמיד ברשותכם");
		open.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				if(!Client.model.isConnected()){
					Client.model.showLogMessage("לפתוח את המקרר האישי");
					open.setUrl("fridge_off.gif");
					return;
				}
				else{
					FillUserFridge();
					dialogBox.center();
					sBox.setFocus(true);
					open.setUrl("fridge_off.gif");
				}
			}
		});
		sBox.getTextBox().addKeyPressHandler(new KeyPressHandler(){
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					addIngredient();
				}
			}
		});
        sBox.addSelectionHandler(new SelectionHandler<Suggestion>(){
                public void onSelection(SelectionEvent<Suggestion> event) {
                        addIngredient();
                }
        });
        
		//the main dialog box
		dialogBox.hide();
		dialogBox.setSize("300px", "500px");
		dialogBox.setText("המקרר שלי");
		dialogBox.setGlassEnabled(true);
        		
        //the add ing panel
		buttonAndBox.add(sBox);
		buttonAndBox.add(addButton);
		
		//the ings table
		ingsTable.getRowFormatter().addStyleName(0, "dataTableHeader");
		ingsTable.setCellPadding(3);
		ingsTable.setBorderWidth(3);
		ingsTable.setWidth("200px");
		ingsTable.addStyleName("MyIngTable");
		scrollerIngsTable.setSize("200px", "410px");
		
		//the close & update buttons panel
		closeButton.setSize("80px", "20px");
		cleanButton.setSize("80px", "20px");
		buttons.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		buttons.add(closeButton);
		buttons.add(cleanButton);
		buttons.setSpacing(3);

		//arrange the left side main panel
		mainVPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		mainVPanel.add(buttonAndBox);
		mainVPanel.add(useFridgeCBox);
		mainVPanel.add(tableHeader);
		mainVPanel.add(scrollerIngsTable);
		mainVPanel.add(buttons);
		mainVPanel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_LEFT);
		
		mainVPanel.setHeight("425px");
		mainVPanel.addStyleName("refrigePanel");
				
		mainHPanel.add(mainVPanel);
		mainHPanel.add(fridgeDoor);
		dialogBox.add(mainHPanel);

        addButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				addIngredient();
			}
		});

		cleanButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {		
				ingsTable.removeAllRows();
				userList.clear();
			}
		});
        
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {		
				//if user asked to add fridge to ClientRequest, add it, and then close fridge
				if(useFridgeCBox.getValue()){
					for(String ingName : userList)
						Client.model.updateUserIngsTable(ingName);
					Client.model.addIngredients(userList);
				}
				updateServerFridge();
				dialogBox.hide();
			}
		});
		
		initWidget(open);
	}
	
	/** add one ingredient to the user fridge */
	private void addIngredient(){
		String ingName = sBox.getText();
		sBox.setText(""); // clear the textBox
		sBox.setFocus(true);
		
		//ing name must be legal
		if (ingName == null || ingName == "" || ingName.startsWith(" ")	|| !ingName.matches("^[א-ת \\']{1,15}$")) {
			sBox.setText(ingName + " אינו שם חוקי");
			return;
		}
		//check if ingredient name is known to server
		if (!Client.model.serverKnowsIngName(ingName)) {
			sBox.setText(ingName + " אינו שם רכיב מוכר");
			return;
		}
		//check if ingredient is already in the fridge
		if(userList.contains(ingName))
			return;
		//add the ingredient to the list and to the table
		userList.add(ingName);
		int i = userList.size()-1;
		ingsTable.setWidget(i / 2, i % 2, newIngNameButton(ingName));
		
	}
	
	/** fill the user fridge with the saved list in server */
	private void FillUserFridge() {
		greetingService.getUserFridgeIngredients(new AsyncCallback<List<String>>() {
			public void onFailure(Throwable caught) {
			}
			public void onSuccess(List<String> result) {
				//clear current fridge
				ingsTable.removeAllRows();
				userList.clear();
				//fill the fridge
				if (result.size()==0){
					return;
				}
				else{
					if (result.get(0).compareTo("t")==0)
						useFridgeCBox.setValue(true);
					else
						useFridgeCBox.setValue(false);
					result.remove(0);
					for(String s : result)
						userList.add(s);
					fillTable();
				}
			}
		});
	}
	
	/** fill the table anew*/
	private void fillTable(){
		ingsTable.removeAllRows();
		int i = 0;
		for(String ingName : userList){	//add result to list, and add to table
			ingsTable.setWidget(i / 2, i % 2, newIngNameButton(ingName));
			i++;
		}
	}
	
	/** send to server the user's fridge list */
	private void updateServerFridge(){
		greetingService.updateMyFridge(userList, useFridgeCBox.getValue(), new AsyncCallback<Boolean>() {
			public void onFailure(Throwable caught) {
					return;				
			}
			public void onSuccess(Boolean result) {
				if (result){
					Client.model.setInfoTextAndPO("מקרר עודכן בהצלחה");
				}
				else{
					Client.model.setInfoTextAndPO("תקלה בעדכון מקרר");
				}
				Client.model.setInfoText("d");
			}
		});
	}
	
	/** create a button with ing name. when clicked, removes the ing from the table and from the list */
	private Button newIngNameButton(final String ingName){
		Button b = new Button(ingName);
		b.setTitle("לחץ למחיקה");
		b.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				userList.remove(ingName);
				fillTable();
			}
		});
		return b;
	}
	
	/** in small resolution set the elements smaller */
	public void setSmaller(){
		dialogBox.setSize("300px", "400px");
		fridgeDoor.setUrl("refrigerator_door_small.gif");
		scrollerIngsTable.setSize("200px", "300px");
	}	
}